package com.zhuiyun.project.security.customizelogin.usernamepasswordcode;

import com.zhuiyun.project.api.sysUser.entiy.SysUser;
import com.zhuiyun.project.api.sysUser.service.SysUserService;
import com.zhuiyun.project.common.errorCode.EmErrorCode;
import com.zhuiyun.project.util.constants.CommonConstants;
import com.zhuiyun.project.security.commonhandler.RequestMethodVerification;
import com.zhuiyun.project.security.commonhandler.SecurityLoginUser;
import com.zhuiyun.project.security.commonhandler.SecurityLoginUserVerification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @ClassName CustomLoginFilter
 * @Description 自定义用户名密码验证码登录逻辑
 * @Author zcy
 * @Date 2023/4/5 11:34
 **/
public class UsernamePasswordCodeFilter extends AbstractAuthenticationProcessingFilter {
    public UsernamePasswordCodeFilter(String defaultFilterProcessesUrl) {
        super(defaultFilterProcessesUrl);
    }
    @Autowired
    SysUserService sysUserService;
    @Resource
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        // 仅使用POST方法提交
        RequestMethodVerification.postVerification(request);
        // 获取登录信息
        SecurityLoginUser loginUser = SecurityLoginUserVerification.getLoginUser(request);
        // 获取信息
        String username = loginUser.getUsername();
        String password = loginUser.getPassword();
        String code = loginUser.getCode();
        //验证是否为空
        SecurityLoginUserVerification.vitParams(username,EmErrorCode.USERNAME_IS_NULL.getErrMsg());
        //验证是否为空
        SecurityLoginUserVerification.vitParams(password,EmErrorCode.PASSWORD_IS_NULL.getErrMsg());
        // 查看code在redis中是否过期
        String key = CommonConstants.CACHE_USER_PASSWORD_CODE+code;
        SecurityLoginUserVerification.VitRedisKey(key,EmErrorCode.CODE_IS_ERROR.getErrMsg());
        //获取用户信息
        SysUser user = sysUserService.getUserByLoginName(username);
        SecurityLoginUserVerification.vitParams(user,EmErrorCode.USER_NOT_EXIST.getErrMsg());
        // 验证密码
        boolean matches = bCryptPasswordEncoder.matches(password, user.getPassword());
        if(!matches){
            throw new AuthenticationServiceException(EmErrorCode.USER_PASSWORD_ERROR.getErrMsg());
        }
        // 检查验证码
        UsernamePasswordCodeAuthenticationToken token = new UsernamePasswordCodeAuthenticationToken(user,code,new ArrayList());
        //获取 头部信息 让合适的provider 来验证他
        token.setDetails(this.authenticationDetailsSource.buildDetails(request));
        //交给 manager 发证
        return this.getAuthenticationManager().authenticate(token);
    }
}
